import { useUserStore } from '@/store/user'
import ajax, { AjaxRequestConfig } from 'uni-ajax'
import envConfig from '@/utils/app_env'
const ajaxList: any[] = []
let isRefresh = false
// #ifndef H5
import getMockBody from '../../mock/_mock'
// #endif

// 错误提示弹窗
const message = (msg: string) => {
  uni.showToast({ title: msg, icon: 'none', duration: 1500 })
}

/**
 * 请求失败后的错误统一处理
 * @param {Number} status 请求失败的状态码
 */
const errorHandle = (status: number, msg: string) => {
  // 状态码判断
  switch (status) {
    // -1: 未登录状态，跳转登录页
    case -1:
      toLogin()
      break
    // 清除token并跳转登录页
    case 401:
      toLogin()
      break
    case 403:
      message(msg || '系统出错')
      break
    // 404请求不存在
    case 404:
      message(msg || '请求的资源不存在')
      break
    default:
      message(msg || '请求出错')
      break
  }
}
// 重新登录，清除token及本地存储的用户数据
const toLogin = () => {
  uni.clearStorageSync()
  useUserStore().refreshToken = ''
  useUserStore().accessToken = ''
  uni.reLaunch({
    url: '/pages/login/index'
  })
}

const $ajax = ajax.create({
  // 初始配置
  baseURL: envConfig.VUE_APP_URL, // 根据环境拿到对应后端url
  header: {
    'Content-Type': 'application/json',
    'Accept-Language': 'zh-CN'
  },
  // 请求时长
  timeout: 1000 * 5
})

// 添加请求拦截器
$ajax.interceptors.request.use(
  config => {
    uni.showLoading({ title: '正在加载中' })
    const { accessToken } = useUserStore()
    // 设置请求头Authorization
    accessToken && (config.header.Authorization = `Bearer ${accessToken}`)

    return config
  },
  error => {
    // 对请求错误做些什么
    return Promise.resolve(error)
  }
)
// refreshToken用户认证
function refreshToken(config: AjaxRequestConfig) {
  config.url = config.url?.replace(config.baseURL || '', '')
  return new Promise((resolve) => {
    ajaxList.push(() => {
      $ajax(config)
        .then((res) => {
          resolve(res)
        })
    })
    if (!isRefresh) {
      isRefresh = true
      $ajax.post({
        url: '/app/user/login/token/refresh', // 用户认证接口
        header: {
          refreshToken: useUserStore().refreshToken,
          accessToken: useUserStore().accessToken
        }
      }).then((res: any) => {
        isRefresh = false
        useUserStore().refreshToken = res.data.refresh_token
        useUserStore().accessToken = res.data.access_token
        while (ajaxList.length) ajaxList.shift()()
      })
    }
  })
}
// 错误响应处理
// 添加响应拦截器
$ajax.interceptors.response.use(
  res => {
    uni.hideLoading()
    return res.statusCode === 200 ? Promise.resolve(res.data) : Promise.reject(res)
  },
  response => {
    uni.hideLoading()
    // 当为app环境且为本地时返回mock数据结果
    // #ifndef H5
    if (envConfig.VUE_APP_MODE === 'development') {
      return getMockBody(response.config)
    }
    // #endif
    // 响应拦截，根据业务需求及后端返回自行修改
    if (response) {
      if (!response.statusCode) {
        return Promise.resolve({ ...response, msg: '请求失败' })
      }
      if (response.errMsg.includes('timeout')) {
        message('请求超时')
      }
      ![400, 500, 406].includes(response.statusCode) && errorHandle(response.statusCode, response.data.msg || response.data.message)
      // GET请求错误统一提示，页面可以省略错误提示
      if (response.statusCode === 500 && !response.success) {
        message(response.data.msg || response.data.message || '获取数据出错')
      }
      return response.statusCode === 406 ? Promise.resolve(refreshToken(response.config)) : ![400, 500].includes(response.statusCode) ? Promise.reject(response) : Promise.resolve(response.data)
    }
  }
)

export default $ajax
